package com.rdtravel.entities;

import com.rdtravel.exceptions.NotEnoughAvaiableSeatsException;
import com.rdtravel.valueobjects.Period;

import java.io.Serializable;
import java.math.BigDecimal;

import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Version;
import javax.validation.Valid;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlTransient;

import org.springframework.format.annotation.NumberFormat;
import org.springframework.format.annotation.NumberFormat.Style;

@Entity
@Table(name = "trips")
@XmlAccessorType(XmlAccessType.FIELD)
public class Trip implements Serializable {
	private static final long serialVersionUID = 1L;
	@Id
	@GeneratedValue
	@XmlAttribute
	private long id;
	@ManyToOne
	@JoinColumn(name = "destinationid")
	@NotNull
	private Destination destination;
	@ManyToOne
	@JoinColumn(name = "departurelocationid")
	@NotNull
	private DepartureLocation departureLocation;
	@ManyToOne(fetch=FetchType.LAZY)
	@JoinColumn(name = "partnerid")
	@NotNull
	private Partner partner;
	@Embedded
	@NotNull
	@Valid
	private Period period;
	@Min(0)
	private int availableSeats;
	@NumberFormat(style = Style.NUMBER)
	@NotNull
	@DecimalMin("0")
	private BigDecimal pricePerDay;
	@Version
	@SuppressWarnings("unused")
	@XmlTransient
	private long version;

	public void bookSeats(Booking booking) {
		if (booking.getSeats() > availableSeats) {
			throw new NotEnoughAvaiableSeatsException();
		}
		availableSeats -= booking.getSeats();
	}

	public long getId() {
		return id;
	}

	public int getAvailableSeats() {
		return availableSeats;
	}

	public void setAvailableSeats(int availableSeats) {
		this.availableSeats = availableSeats;
	}

	public Period getPeriod() {
		return period;
	}

	public void setPeriod(Period period) {
		this.period = period;
	}

	public BigDecimal getPricePerDay() {
		return pricePerDay;
	}

	public void setPricePerDay(BigDecimal pricePerDay) {
		this.pricePerDay = pricePerDay;
	}

	@Override
	public String toString() {
		return "Trip [id=" + id + ", period=" + period + "]";
	}

	@NumberFormat(style = Style.NUMBER)
	public BigDecimal getGrossPricePerPerson() {
		return pricePerDay.multiply(new BigDecimal(period.getNumberOfDays()));
	}

	public Destination getDestination() {
		return destination;
	}

	public void setDestination(Destination destination) {
		this.destination = destination;
	}

	public DepartureLocation getDepartureLocation() {
		return departureLocation;
	}

	public void setDepartureLocation(DepartureLocation departureLocation) {
		this.departureLocation = departureLocation;
	}

	public Partner getPartner() {
		return partner;
	}

	public void setPartner(Partner partner) {
		this.partner = partner;
	}
	

}
